//使用compile_run模块完成网络服务（用户的代码编译请求）
#include "compile_run.hpp"     //引入编译运行模块
#include "compile_run4.hpp"    //引入编译运行模块（竞赛版）
#include "../common/log.hpp"   //引入日志模块
#include "../common/httplib.h" //引入第三方开源库：httplib.h 来负责网络通信服务（这里可以自己写一个TCP通信模块来代替）

using namespace ns_compile_run;//展开编译运行模块
using namespace ns_compile_run4;//展开编译运行模块
using namespace ns_log;        //展开编译运行模块
using namespace httplib;       //展开httplib库

int main(int argc, char* argv[])
{
    if(argc != 2) //传入参数不足两个
    {
        LOG(ERROR) << "未传入端口号，无法使用compile_run模块完成网络服务\n";
        return 1;
    }

    /*实例化一个Server对象，Server对象中有一个请求与处理路由表，记录各种请求对应的处理函数。*/
    Server svr;
    
    /*注册请求路由，告诉httplib，哪个请求应该用哪个函数处理。*/
    //对用户发起的compile_and_run请求进处理，处理方式在后面的lambda函数中
    svr.Post("/compile_and_run", [](const Request &req/*请求类*/, Response &resp/*响应类*/){
        // 1.获取用户编译运行请求后网站发来的Json串
        std::string in_json = req.body; //Json串在请求类的正文中(req.body)(用户请求的服务正文就是用户上传的json字符串)。
        std::string out_json; //用来接收编译运行模块返回的Json串。
        if(!in_json.empty())  //如果用户上传的json串不为空。
        {           
        // 2.调用编译运行整合模块
            CompileAndRun::Start(in_json, &out_json); //调用编译运行模块。
        // 3.将保存编译运行结果的Json串返回给用户
            resp.set_content(out_json, "application/json;charset=utf-8"); //将编译运行模块返回的Json串返回给用户。
        }/*application/json:json类型数据；charset=utf-8:编码类型=utf-8*/
    });

    //对用户发起的compile_and_run4请求(竞赛题目编译)进处理，处理方式在后面的lambda函数中
    svr.Post("/compile_and_run4", [](const Request &req/*请求类*/, Response &resp/*响应类*/){
        // 1.获取用户编译运行请求后网站发来的Json串
        std::string in_json = req.body; //Json串在请求类的正文中(req.body)(用户请求的服务正文就是用户上传的json字符串)。
        std::string out_json; //用来接收编译运行模块返回的Json串。
        if(!in_json.empty())  //如果用户上传的json串不为空。
        {           
        // 2.调用编译运行整合模块
            CompileAndRun4::Start(in_json, &out_json); //调用编译运行模块。
        // 3.将保存编译运行结果的Json串返回给用户
            resp.set_content(out_json, "application/json;charset=utf-8"); //将编译运行模块返回的Json串返回给用户。
        }/*application/json:json类型数据；charset=utf-8:编码类型=utf-8*/
    });


    /*搭建服务器，开始监听。*/
    svr.listen("0.0.0.0", atoi(argv[1])); //argv[1]是一个字符串，用atoi()转为整数


    //以下代码为未连接网络时的本地测试代码。
    //// 1.接收用户的Json串
    // std::string in; //模拟用户输入的Json串
    // Json::Value in_Json;
    // /* R"xxxx" : 原生字符串(Raw string)，C++11引入，在字符串前加一个R，再用()将字符串内容包起来，能让字符串保持原样输出，不会再解析特殊符号*/
    // in_Json["code"] = R"(#include<iostream>
    // int main(){
    //     int a = 3/0;
    //     std::cout << "你可以看见我了" << std::endl;
    //     return 0;
    // })";
    // in_Json["input"] = "";
    // in_Json["cpu_limit"] = 1;
    // in_Json["mem_limit"] = 102400;
    // Json::FastWriter writer; // 中间类，将Json类转为其他数据类型。非格式化。
    // in = writer.write(in_Json);
    //// 2.调用编译运行整合模块并将结果Json串返回给用户。
    // std::string out; //模拟给用户端返回信息的Json字符串
    // CompileAndRun::Start(in, &out);
    // std::cout << out << std::endl;
    return 0;
}

